package four.ppt;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by zhour on 2016/8/31.
 */
public class PPTTest {

    @Test
    public void test(){
        List<Integer> costBeforeTax = Arrays.asList(100,200,300,400,500);
        double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost)
                .reduce((sum,cost)->sum+cost).get();
        System.out.println("Total:"+bill);


        Student[] students = new Student[20];
        for (int i = 0;i < 20; i++){
            Student student = new Student(UUID.randomUUID().toString(),20+i);
            students[i] = student;
        }

        Arrays.sort(students,(Student stu1, Student stu2)->{return Integer.compare(stu1.getAge(),stu2.getAge());});
        Arrays.sort(students,(Student stu1, Student stu2)-> Integer.compare(stu1.getAge(),stu2.getAge()));
        Arrays.sort(students,(stu1, stu2)-> Integer.compare(stu1.getAge(),stu2.getAge()));

        Function<Student,String> studentStringFunction = p -> "\nname:"+p.getName()+",age:"+p.getAge();

        System.out.println(studentStringFunction.apply(students[0]));

        Predicate<String> predicate = p ->  p != null;
        System.out.println( predicate.test(null));
        System.out.println( predicate.test("1"));

        UnaryOperator<String> unaryOperator = p -> p == null ? "null": p;
        System.out.println(unaryOperator.apply(null));
        System.out.println(unaryOperator.apply("1"));

        BiFunction<String,Integer,Student> biFunction = (s,i) -> new Student(s,i);

        System.out.println(biFunction.apply("aa",19));

        Consumer<Integer> b1 = System::exit;
        Consumer<String[]> b2 = Arrays::sort;

        List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
        myList.stream().filter(s->s.startsWith("a")).map(String::toUpperCase).sorted().forEach(System.out::println);


        Stream.of("a1","a2","a3").map(s->s.substring(1)).mapToInt(Integer::parseInt).max().ifPresent(System.out::println);


        List<Person> persons = Arrays.asList( new Person("Max", 18), new Person("Peter", 23), new Person("Pamela", 23), new Person("David", 12));

        persons.parallelStream().reduce(0, (sum, p) -> {
            System.out.format("accumulator: sum=%s; person=%s [%s]\n", sum, p, Thread.currentThread().getName());
            return sum += p.getAge();
        }, (sum1, sum2) -> {
            System.out.format("combiner: sum1=%s; sum2=%s [%s]\n", sum1, sum2, Thread.currentThread().getName());
            return sum1 + sum2;
        });

        persons.stream().reduce((p1,p2)->p1.getAge()>p2.getAge() ? p1:p2).ifPresent(person -> System.out.println(person.getName()));

        List<Person> filtered = persons.stream().filter(p -> p.getName().startsWith("P")).collect(Collectors.toList());

        System.out.println(filtered);

        Map<Integer, List<Person>> personsByAge = persons.stream().collect(Collectors.groupingBy(p -> p.getAge()));

        personsByAge.forEach((age, p) -> System.out.format("age %s: %s\n", age, p));

        Double averageAge = persons.stream().collect(Collectors.averagingInt(p -> p.getAge()));
        System.out.println(averageAge);     // 19.0


        List<String> list2 = Arrays.asList("adf", "bcd", "abc", "hgr", "jyt", "edr", "biu");
        String result = list2.stream().collect(StringBuilder::new, (res, item) -> { res.append(' ').append(item); } , (res1, res2) -> {
            System.out.printf(Thread.currentThread().getName()+" res1=%s,res2=%s \r\n", res1, res2); res1.append(res2); } ).toString(); System.out.println("result " + result);
        //accumulator
                //supplier
        //combiner
        list2.parallelStream();
    }
}

class Student{
    private int age;
    private String name;

    public Student(){
    }
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Person{
private int age;
private String name;

public Person(){
        }
public Person(String name, int age){
        this.name = name;
        this.age = age;
        }

public int getAge() {
        return age;
        }

public void setAge(int age) {
        this.age = age;
        }

public String getName() {
        return name;
        }

public void setName(String name) {
        this.name = name;
        }
        }
